<?php
namespace Tlf\User;
use Cartalyst\Sentinel\Native\Facades\Sentinel;
/**
* A wrapper for all things Sentinel, so this SHOULD be the ONLY place that has a reference to Sentinel
*/
class Backend {
protected $capsule;
protected $core;
protected $package;
public function __construct(\Lia\Compo $core){
$this->core = $core;
$this->package = $core->package;
}
public function getPdo(){
$pdo = new \PDO($this->package->get('DB.driver')
.':host='.$this->package->get('DB.host').';dbname='.$this->package->get('DB.database'),
$this->package->get('DB.user'), $this->package->get('DB.password')
);
return $pdo;
}
//
// global stuffs
//
public function connectDb(){
$package = $this->package;
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule->addConnection($dbInfo = [
'driver' => $package->get('DB.driver'),
'host' => $package->get('DB.host'),
'charset' => $package->get('DB.charset'),
'collation' => $package->get('DB.collation'),
'database' => $package->get('DB.database'),
'username' => $package->get('DB.user'),
'password' => $package->get('DB.password'),
]);
$capsule->bootEloquent();
$this->capsule = $capsule;
}
public function getSqlCreate(){
$createSql = file_get_contents($package->dir().'/files/sentinel-db.sql');
return $createSql;
}
//
// user information
//
public function updateUserFirstName($model, $newFirstName){
Sentinel::update($model, ['first_name'=>$newFirstName]);
}
public function updateUserLastName($model, $newLastName){
Sentinel::update($model, ['last_name'=>$newLastName]);
}
public function updateUserEmail($model, $newEmail){
Sentinel::update($model, ['email'=>$newEmail]);
}
public function deleteUser($model){
$model->delete();
}
//
//user state on site
//
public function logoutUser(){
$model = Sentinel::forceCheck();
if ($model)Sentinel::logout($model);
}
public function login($model){
$didLogin = Sentinel::login($model, true);
return $didLogin;
}
public function logoutEverywhere($model){
return Sentinel::logout($model, true);
}
//
// user state in backend
//
public function register($email, $name, $password){
$credentials = [
'email'=>$email,
'name'=>$name,
'password'=>$password
];
$model = Sentinel::register($credentials);
return $model;
}
public function setPassword($model, $newPassword){
return Sentinel::update($model,[
'password'=>$newPassword
]);
}
//
//user retrieval
//
public function getLoggedInUser(){
return Sentinel::check();
}
public function userFromEmail($email){
$model = Sentinel::findUserByCredentials(['email'=>$email]);
return $model;
}
public function authenticate($email, $password){
$model = Sentinel::authenticate(
[ 'email'=>$email,
'password'=> $password,
]
);
return $model;
}
public function userById($id){
$model = Sentinel::findUserById($id);
return $model;
}
//
//activations
//
public function removeActivation($model){
return Sentinel::getActivationRepository()->remove($model);
}
public function newActivationCode($sentinelUser){
$activation = Sentinel::getActivationRepository()->create($sentinelUser);
return $activation['code'];
}
public function completeActivation($model, $code){
//@TODO test & make sure that `complete`ing an already complete activation code will return true. Since registration & reset password use the same system (activation codes), and we don't want to de-activate an account when a password reset is requested... we'll be completing an already complete code when someone is changing their password.
$didActivate = Sentinel::getActivationRepository()->complete($model, $code);
return $didActivate;
}
public function hasCompletedActivation($model){
if (Activation::completed($model))return true;
return false;
}
//
// user permissions & roles
//
//
public function getRoles($user){
if ($user->model()==null)return [];
$pdo = $this->core->getPdo();
$query =
<<<SQL
SELECT roles.* FROM roles
JOIN role_users
ON role_users.role_id = roles.id
WHERE
role_users.user_id = :user_id
SQL;
$st = $pdo->prepare($query);
$st->execute([':user_id'=>$user->id]);
return $st->fetchAll(\PDO::FETCH_ASSOC);
}
public function getRoleFromSlug($roleName){
$role = Sentinel::findRoleBySlug($roleName);
return $role;
}
public function createRole($roleName){
$roleRepo = Sentinel::getRoleRepository();
$role = $roleRepo->create([
'name'=>$roleName,
'slug'=>$roleName
]);
return $role;
}
public function addRole($user, $roleName){
$role = $this->getRoleFromSlug($roleName);
if ($role==null)$role = $this->createRole($roleName);
try {
$role->users()->attach($user->model());
} catch (\PDOException $e){
return $role;
}
return $role;
}
public function getPermissions($user){
return $user->model()->getPermissions();
}
protected function permissionKey($action, $withId){
if ($withId!=null)$action .= '-'.$withId;
return $action;
}
public function permit($user, $action, $withId=null){
$action = $this->permissionKey($action,$withId);
// $user->model()->addPermission($action);
$user->model()->updatePermission($action, true, true);
$user->model()->save();
}
public function revoke($user, $action, $withId=null){
$action = $this->permissionKey($action,$withId);
$user->model()->removePermission($action);
$user->model()->save();
}
public function forbid($user, $action, $withId=null){
$action = $this->permissionKey($action,$withId);
$user->model()->updatePermission($action, false, true);
$user->model()->save();
}
public function can($user, $action, $withId=null){
$action = $this->permissionKey($action,$withId);
return $user->model()->hasAccess([$action]);
}
public function isRole($user, $role){
if ($user->model()==null)return false;
$userId = $user->id;
$role = strtolower($role);
$pdo = $this->core->getPdo();
$query =
<<<SQL
SELECT roles.slug AS role_slug, roles.id AS role_id, role_users.user_id AS user_id FROM roles
JOIN role_users ON
role_users.role_id = roles.id
WHERE roles.slug LIKE :slug
AND role_users.user_id = :user_id
SQL;
$statement = $pdo->prepare($query);
$statement->execute([':slug'=>$role, ':user_id' => $userId]);
$rows = $statement->fetchAll(\PDO::FETCH_ASSOC);
if (count($rows)<1)return false;
$r = $rows[0];
if (strtolower($r['role_slug'])==$role
&& $r['user_id']==$userId
&& $r['role_id']!=null
) {
return true;
}
return false;
}
}